home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / DYN401.ZIP / class / date.d < prev    next >
Text File  |  1997-02-06  |  9KB  |  500 lines

  1.  
  2. /*
  3.  *
  4.  *    Copyright (c) 1993-1996 Algorithms Corporation
  5.  *    3020 Liberty Hills Drive
  6.  *    Franklin, TN  37067
  7.  *
  8.  *    ALL RIGHTS RESERVED.
  9.  *
  10.  *
  11.  *
  12.  */
  13.  
  14.  
  15. #include <string.h>
  16. #include <math.h>
  17. #include <time.h>
  18.  
  19.  
  20. defclass  Date : LongInteger  {
  21.     init:    init_class;
  22. };
  23.  
  24.  
  25.  
  26. static    gLongValue_t        longValue;/*  local cache LongValue method  */
  27. static    gChangeLongValue_t    changeLongValue;
  28.  
  29.  
  30. static    char    *Dtfmt(long d, char *s)    /*  format date    yyyymmdd  to mm/dd/yy  */
  31. {
  32.     int    i;
  33.     char    v[7];
  34.  
  35.     s[8] = '\0';
  36. /*
  37.     if (d >= 20000101L  &&  d < 20900101L)
  38.         d -= 10000L;
  39.     if (d < 19000101L  ||  d > 19991231L)    {
  40.         for (i=0 ; i != 8 ; )    s[i++] = '*';
  41.         return(s);
  42.     }
  43. */
  44.     if (d < 101L)  {
  45.         for (i=0 ; i != 8 ; )
  46.             s[i++] = ' ';
  47.         return(s);
  48.     }
  49.     d %= 1000000L;
  50.     sprintf(v, "%6ld", d);
  51.     s[0] = v[2] == '0' ? ' ' : v[2];
  52.     s[1] = v[3];
  53.     s[2] = '/';
  54.     s[3] = v[4];
  55.     s[4] = v[5];
  56.     s[5] = '/';
  57.     s[6] = v[0] == ' ' ? '0' : v[0];
  58.     s[7] = v[1] == ' ' ? '0' : v[1];
  59.     return(s);
  60. }
  61.  
  62. #if 0
  63.  
  64. static    char    *Dtfmt4(long d, char *s)    /*  format date    yyyymmdd  to mm/dd/yyyy     */
  65. {
  66.     int    i;
  67.     char    v[9];
  68.  
  69.     if (d <= 0L  ||  d > 99991231L)  {
  70.         for (i=0 ; i != 10 ; )
  71.             s[i++] = ' ';
  72.         s[i] = '\0';
  73.         return(s);
  74.     }
  75.     sprintf(v, "%8ld", d);
  76.     s[0] = (v[4] ==    '0') ? ' ' : v[4];
  77.     s[1] = v[5];
  78.     s[2] = '/';
  79.     s[3] = v[6];
  80.     s[4] = v[7];
  81.     s[5] = '/';
  82.     s[6] = v[0];
  83.     s[7] = v[1];
  84.     s[8] = v[2];
  85.     s[9] = v[3];
  86.     s[10] =    '\0';
  87.     return(s);
  88. }
  89.  
  90. #endif
  91.  
  92. static    long    Jul(long x)        /*  converts cal yyyymmdd to julian day     */
  93. {
  94.     long    d, y;
  95.     long    m;
  96.  
  97.     if (x <= 0L)        return(x);
  98.     y = x /    10000L;
  99.     m = (x % 10000L) / 100L;
  100.     d = x %    100L;
  101.     d += (long) (.5 + (m - 1L) * 30.57);
  102.     if (m >    2L)  {
  103.         d--;
  104. /*  Had to convert to the following lines because of bug in MSVC 1.0
  105.         if (0L != y % 400L  &&  (0L != y % 4L  ||  0L == y % 100L))
  106.             d--;
  107. */
  108.         if (0L != y % 400L  &&  0L != y % 4L)
  109.             d--;
  110.         else if (0L != y % 400L  &&  0L == y % 100L)
  111.             d--;
  112.     }
  113.     d += (long) (365.25 * --y);
  114.     d += y / 400L;
  115.     d -= y / 100L;
  116.     return(d);
  117. }
  118.  
  119. static    long Cal(long d)        /*  converts julian date to calander yyyymmdd */
  120. {
  121.     long    y, m, t;
  122.  
  123.     if (d <= 0L)        return(d);
  124.     y = (long)(1.0 + d / 365.2425);
  125.     t = y -    1L;
  126.     d -= (long) (t * 365.25);
  127.     d -= t / 400L;
  128.     d += t / 100L;
  129.     if (d >    59L  &&     0L != y % 400L     &&  (0L != y %    4  ||  0L == y % 100L))
  130.         d++;
  131.     if (d >    60L)    
  132.         d++;
  133.     m = (long)((d + 30L) / 30.57);
  134.     d -= (long) floor(.5 + (m - 1L)    * 30.57);
  135.     if (m == 13)  {
  136.         m = 1;
  137.         ++y;
  138.     }  else  if (!m)  {
  139.         m = 12;
  140.         --y;
  141.     }
  142.     return 10000L * y + m * 100L + d;
  143. }
  144.  
  145. static    char    *Dyofwk(long d, char *s)        /* day of week routine    */
  146. {
  147.     int    i;
  148.     char    *p;
  149.  
  150.     if (d <= 0L)
  151.         if (s)  {
  152.             *s = '\0';
  153.             return(s);
  154.         }  else
  155.             return("");
  156.     i = Jul(d) % 7L;
  157.     switch    (i)  {
  158.     case  0:    p = "Sunday";        break;
  159.     case  1:    p = "Monday";        break;
  160.     case  2:    p = "Tuesday";        break;
  161.     case  3:    p = "Wednesday";    break;
  162.     case  4:    p = "Thursday";        break;
  163.     case  5:    p = "Friday";        break;
  164.     case  6:    p = "Saturday";        break;
  165.     default:    p = "";            break;
  166.     }
  167.     if (s)  {
  168.         strcpy(s, p);
  169.         return(s);
  170.     }  else
  171.         return(p);
  172. }
  173.  
  174. static    char    *Mmofyr(int m, char *s)        /* month of year  */
  175. {
  176.     char    *p;
  177.     
  178.     if (m <= 0)
  179.         if (s)  {
  180.             *s = '\0';
  181.             return(s);
  182.         }  else
  183.             return("");
  184.     m = (m - 1) % 12;
  185.     switch (m)  {
  186.     case  0:    p = "January";        break;
  187.     case  1:    p = "February";        break;
  188.     case  2:    p = "March";        break;
  189.     case  3:    p = "April";        break;
  190.     case  4:    p = "May";        break;
  191.     case  5:    p = "June";        break;
  192.     case  6:    p = "July";        break;
  193.     case  7:    p = "August";        break;
  194.     case  8:    p = "September";    break;
  195.     case  9:    p = "October";        break;
  196.     case 10:    p = "November";        break;
  197.     case 11:    p = "December";        break;
  198.     default:    p = "";            break;
  199.     }
  200.     if (s)  {
  201.         strcpy(s, p);
  202.         return(s);
  203.     }  else
  204.         return(p);
  205. }
  206.  
  207. static    short    *Timemark(short int *v)
  208. {
  209.     struct    tm    *a;
  210. /*
  211.       extern    struct    tm    *localtime();
  212.     extern    long    time();
  213. */
  214.     time_t    t;
  215.  
  216.     time(&t);
  217.     a = localtime(&t);
  218.     v[0] = a->tm_year + 1900;
  219.     v[1] = a->tm_mon + 1;
  220.     v[2] = a->tm_mday;
  221.     v[3] = a->tm_hour;
  222.     v[4] = a->tm_min;
  223.     v[5] = a->tm_sec;
  224.     v[6] = 0;
  225.     return v;
  226. }
  227.  
  228. static    long _Today(void)
  229. {
  230.     short    v[7];
  231.  
  232.     Timemark(v);
  233.     return 10000L * (long) v[0] + 100L * (long) v[1] + (long) v[2];
  234. }
  235.  
  236. static    long    Date_ymd(long date, int *year, int *month, int *day)
  237. {
  238.     register int  temp;
  239.  
  240.     temp = (int) (date % 10000L);
  241.  
  242.     if (year)        *year  = (int) (date / 10000L);
  243.     if (month)        *month = temp /    100;
  244.     if (day)        *day   = temp %    100;
  245.     return(date);
  246. }
  247.  
  248. static    long    Ymd_date(int year, int month, int day)
  249. {
  250.     return((long) year * 10000L + (long) month * 100L + (long) day);
  251. }
  252.  
  253. static    char    *Num_sufx(int d)
  254. {
  255.     register int   i = d % 10;
  256.  
  257.     if (i == 1 && d    != 11)
  258.         return "st";
  259.     else if    (i == 2    && d !=    12)
  260.         return "nd";
  261.     else if    (i == 3    && d !=    13)
  262.         return "rd";
  263.     else    return "th";
  264. }
  265.  
  266. static    char    *Time2(char *buf)
  267. {
  268.     short    v[7], t=0;
  269.  
  270.     Timemark(v);
  271.     if (v[3] >= 12)     {
  272.         t = 1;
  273.         if (v[3] > 12)        v[3] -=    12;
  274.     }
  275.     sprintf(buf, "%2d:%2d %s",
  276.         (int) v[3], (int) v[4], t ? "PM" : "AM");
  277.     if (buf[3] == ' ')
  278.         buf[3] = '0';
  279.     return(buf);
  280. }
  281.  
  282. static    char    *DateFmt(char *buf, long dt, char *msk)
  283. {
  284.     int    y, m, d;
  285.     char    tmp[20], *bp = buf;
  286.  
  287.     if (dt <= 0L)  {
  288.         *buf = '\0';
  289.         return(buf);
  290.     }
  291.     Date_ymd(dt, &y, &m, &d);
  292.     while (*msk)
  293.         if (*msk != '%')
  294.             *bp++ = *msk++;
  295.         else
  296.             switch (*++msk)  {
  297.             case '\0':
  298.                 break;
  299.             case '%':
  300.             default:
  301.                 *bp++ = *msk++;
  302.                 break;
  303.             case 'W':        /*  Day of week  */
  304.             case 'w':
  305.                 strcpy(bp, Dyofwk(dt, NULL));
  306.                 bp += strlen(bp);
  307.                 msk++;
  308.                 break;
  309.             case 'M':    /*  Month of the year  */
  310.                 strcpy(bp, Mmofyr(m, NULL));
  311.                 bp += strlen(bp);
  312.                 msk++;
  313.                 break;
  314.             case 'm':    /*  Month name abreveation  */
  315.                 strcpy(bp, Mmofyr(m, NULL));
  316.                 bp += 3;
  317.                 msk++;
  318.                 break;
  319.             case 'd':    /*  Day of the month  */
  320.                 sprintf(bp, "%d", d);
  321.                 bp += strlen(bp);
  322.                 msk++;
  323.                 break;
  324.             case 'D':    /*  Day of the month  */
  325.                 sprintf(bp, "%2d", d);
  326.                 for ( ; *bp ; ++bp)
  327.                     if (*bp == ' ')
  328.                         *bp = '0';
  329.                 msk++;
  330.                 break;
  331.             case 'y':        /*  Year  93  */
  332.                 sprintf(bp, "%2d", y%100);
  333.                 for ( ; *bp ; ++bp)
  334.                     if (*bp == ' ')
  335.                         *bp = '0';
  336.                 msk++;
  337.                 break;
  338.             case 'Y':    /*  Year  1993  */
  339.                 sprintf(bp, "%4d", y);
  340.                 bp += strlen(bp);
  341.                 msk++;
  342.                 break;
  343.             case 'S':    /*  Numeric Suffix  */
  344.             case 's':
  345.                 strcpy(bp, Num_sufx(d));
  346.                 bp += strlen(bp);
  347.                 msk++;
  348.                 break;
  349.             case 'n':    /*  Month number  */
  350.                 sprintf(bp, "%d", m);
  351.                 bp += strlen(bp);
  352.                 msk++;
  353.                 break;
  354.             case 'N':    /*  Month number  */
  355.                 sprintf(bp, "%2d", m);
  356.                 bp += strlen(bp);
  357.                 msk++;
  358.                 break;
  359.             case 'T':    /*  current time  */
  360.             case 't':
  361.                 strcpy(bp, Time2(tmp));
  362.                 bp += strlen(bp);
  363.                 msk++;
  364.                 break;
  365.             }
  366.     *bp = '\0';
  367.     return(buf);
  368. }
  369.  
  370. static    long    Add_days(long date, long days)
  371. {
  372.     if (date <= 0L)        return(0L);
  373.     return Cal(days + Jul(date));
  374. }
  375.  
  376. static    long    Add_mon(long date, int months)
  377. {
  378.     int    y, m, d;
  379.     long    mon;
  380.  
  381.     if (date <= 0L)        return(0L);
  382.     Date_ymd(date, &y, &m, &d);
  383.     mon = 12L * (long) y + (long) m    + (long) months    - 1L;
  384.     y = mon    / 12L;
  385.     m = 1L + mon % 12L;
  386.     date = Ymd_date(y, m, d);
  387.     return(date);
  388. }
  389.  
  390. static    long    Add_year(long date, int years)
  391. {
  392.     int    y, m, d;
  393.  
  394.     if (date <= 0L)        return(0L);
  395.     Date_ymd(date, &y, &m, &d);
  396.     y += years;
  397.     date = Ymd_date(y, m, d);
  398.     return(date);
  399. }
  400.  
  401. static    int    Valid_date(long d)
  402. {
  403.     return d == Cal(Jul(d));
  404. }
  405.  
  406. static    long    Date_dif(long d1, long d2)
  407. {
  408.     return Jul(d1) - Jul(d2);
  409. }
  410.  
  411. imeth    gDayName()
  412. {
  413.     return gNewWithStr(String, Dyofwk(longValue(self), NULL));
  414. }
  415.  
  416. imeth    gMonthName()
  417. {
  418.     int    m;
  419.     Date_ymd(longValue(self), NULL, &m, NULL);
  420.     return gNewWithStr(String, Mmofyr(m, NULL));
  421. }
  422.  
  423. imeth    gFormatDate, <vFormat> (char *msk)
  424. {
  425.     char    buf[80];
  426.  
  427.     return gNewWithStr(String, DateFmt(buf, longValue(self), msk));
  428. }
  429.  
  430. imeth    gStringRepValue()
  431. {
  432.     char    buf[15];
  433.  
  434.     return gNewWithStr(String, Dtfmt(gLongValue(self), buf));
  435. }
  436.  
  437. cmeth    gToday()
  438. {
  439.     return gNewWithLong(self, _Today());
  440. }
  441.  
  442. imeth    gAddDays(long days)
  443. {
  444.     return changeLongValue(self, Add_days(longValue(self), days));
  445. }
  446.  
  447. imeth    gAddMonths(int months)
  448. {
  449.     return changeLongValue(self, Add_mon(longValue(self), months));
  450. }
  451.  
  452. imeth    gAddYears(int years)
  453. {
  454.     return changeLongValue(self, Add_year(longValue(self), years));
  455. }
  456.  
  457. imeth    int    gValidDate()
  458. {
  459.     return Valid_date(longValue(self));
  460. }
  461.  
  462. imeth    long    gDifference(dt)
  463. {
  464.     ChkArgTyp(dt, 2, Date);
  465.     return Date_dif(longValue(self), longValue(dt));
  466. }
  467.  
  468. cmeth    long    gCalToJul(long dt)
  469. {
  470.     return Jul(dt);
  471. }
  472.  
  473. cmeth    long    gJulToCal(long dt)
  474. {
  475.     return Cal(dt);
  476. }
  477.  
  478. imeth    long    gJulian()
  479. {
  480.     return Jul(longValue(self));
  481. }
  482.  
  483. static    void    init_class(void)
  484. {
  485.     longValue = imcPointer(CLASS, gLongValue);
  486.     changeLongValue = imcPointer(CLASS, gChangeLongValue);
  487. }
  488.  
  489. /*
  490.  *
  491.  *    Copyright (c) 1993-1996 Algorithms Corporation
  492.  *    3020 Liberty Hills Drive
  493.  *    Franklin, TN  37067
  494.  *
  495.  *    ALL RIGHTS RESERVED.
  496.  *
  497.  *
  498.  *
  499.  */
  500.